#ifndef __AIRB_INPUT_H__
#define __AIRB_INPUT_H__

/******
	Input Class is dependent on the Video Class
*******/

namespace AIRB
{

void InputSetupGLUT();


class Input
{
public:
	static Input* CreateInstance(Input* inst=NULL)
	{
		if(!singleton_instance)
		{
			if(inst)singleton_instance = inst;
			else singleton_instance = new Input;
		}
		return singleton_instance;
	}

	static Input* Instance(){return Input::singleton_instance;}

	
	//Drag
	bool drag;
	abVec2 drag_start;
	abVec2 drag_current;

	//Mouse positions
	abVec2 mouse_pos;
	abVec2 mouse_pos_act;
	abVec2 mouse_pos_raw;

	//Mouse Buttons
	bool mouse_left;
	bool mouse_right;
	bool mouse_mid;

	//Mouse callbacks
	void Mouse(int button, int state, int x, int y)
	void MouseWheel(int button, int dir, int x, int y){}
	void MouseMoveActive(int x,int y){}
	void MouseMovePassive(int x,int y){}

	//Keyboard Callbacks
	void KeyboardNormal(unsigned char key, int x, int y)
	{

	}

	void KeyboardSpecial(unsigned char key, int x, int y)
	{

	}


	//Mouse position scaled to zoom & translated
	virtual abVec2 scaleMouse(float x,float y)
	{
		float sx = (float)((x- Video::Inst()->window_hwidth)/Video::Inst()->window_view_scale);
		float sy = (float)((-y+Video::Inst()->window_hheight)/Video::Inst()->window_view_scale);

		sx += Video::Inst()->window_view_x;
		sy += Video::Inst()->window_view_y;

		return abVec2(sx,sy);
	}

	//Mouse position scaled to zoom only
	virtual abVec2 scaleMouse_act(float x,float y)
	{
		float sx = (float)((x- Video::Inst()->window_hwidth)/Video::Inst()->window_view_scale);
		float sy = (float)((-y+Video::Inst()->window_hheight)/Video::Inst()->window_view_scale);
		return abVec2(sx,sy);
	}

protected:
	static Input* singleton_instance;

	Input()
	{
		mouse_left = false;
		mouse_right = false;
		mouse_mid = false;
	}
};

void processNormalKeys(unsigned char key, int x, int y) 
{
	Input::Instance()->KeyboardNormal(unsigned char key, int x, int y);
}

void processSpecialKeys(unsigned char key, int x, int y) 
{
	Input::Instance()->KeyboardSpecial(unsigned char key, int x, int y);
}

void processMouse(int button, int state, int x, int y) 
{
	Input::Instance()->Mouse(button,state,x,y);
}

void processMouseWheel(int button, int dir, int x, int y)
{
	Input::Instance()->MouseWheel(button,dir,x,y);
}

void processMouseActiveMotion(int x, int y) 
{
	Input::Instance()->MouseMoveActive(x,y);
}

void processMousePassiveMotion(int x, int y) 
{
	Input::Instance()->MouseMovePassive(x,y);
}

void processMouseEntry(int state) {
}


void InputSetupGLUT()
{
	//Keyboard
	glutKeyboardFunc(processNormalKeys);

	adding here the mouse processing callbacks
	glutMouseFunc(processMouse);
	glutMouseWheelFunc(processMouseWheel);
	glutMotionFunc(processMouseActiveMotion);
	glutPassiveMotionFunc(processMousePassiveMotion);
	glutEntryFunc(processMouseEntry);
}

}

#endif
